package controller;

import group.GeoGroup;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;


import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;

import buildtools.BallAdder;
import buildtools.Connector;
import buildtools.TubeAdder;
import node.GeoNode;
import node.IntersectionValidator;

import com.sun.j3d.utils.picking.PickResult;

import component.AbstractComponent;
import component.Ball;
import component.ComponentFactory;
import component.Status;
import component.Structure;
import component.Tube;
import component.group.ComponentGroup;

public class PlaceNewController extends AbstractController {

	private BallAdder ballAdder;
	private TubeAdder tubeAdder;
	
	private AbstractComponent lastPicked;
	
	private long clickStart = 0;
	
	private ComponentGroup componentGroup = new ComponentGroup();
	
	public PlaceNewController(Canvas3D canvas, BranchGroup bg, Structure structure, ComponentFactory factory) {
		super(canvas, bg);

		Connector connector = new Connector(structure);
		
		ballAdder = new BallAdder(structure, factory, connector);
		tubeAdder = new TubeAdder(structure, factory, connector);
	}

	@Deprecated
	public PlaceNewController(Canvas3D cv, BranchGroup pickable,
			GeoGroup geoNodes, GeoGroup tempNodes) {
		this(cv, pickable, new Structure(geoNodes, tempNodes), new ComponentFactory(new IntersectionValidator(geoNodes)));

		
		
	}

	@Override
	public void activate() {
		
	}

	@Override
	public void deactivate() {
		clearSelection();
	}

	private void clearSelection() {
		if (lastPicked != null)
			this.deselectNode(lastPicked);
		lastPicked = null;

		tubeAdder.clearData();
		ballAdder.clearData();
	}

	private void selectNode(AbstractComponent component) {
		componentGroup.add(component);
		component.setStatus(Status.SELECTED);
	}
	
	private void deselectNode(AbstractComponent component) {
		componentGroup.remove(component);
		component.setStatus(Status.NORMAL);
	}
	
	
	@Override
	public void mouseClicked(MouseEvent e) {}

	@Override
	public void mousePressed(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON3) {
			clickStart  = e.getWhen();
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		
		PickResult pickResult = this.pickClosest(e);
		
		if (pickResult != null && e.getButton() == MouseEvent.BUTTON1) {
			
			AbstractComponent component = ((GeoNode)pickResult.getNode(PickResult.BRANCH_GROUP)).getComponent();

			//Ball
			if (component instanceof Ball) {
				Ball ball = (Ball)component;
				
				if (ballAdder.isActive() && ballAdder.selectBall(ball))
					clearSelection();
				
				if (tubeAdder.hasFreeSlots(ball)) {
					clearSelection();
					
					tubeAdder.addToBall(ball);
					lastPicked = component;
					
					this.selectNode(component);
				} 
			}
			
			//Tube
			else if (component instanceof Tube) {
				Tube tube = (Tube)component;
				
				if (tubeAdder.isActive() && tubeAdder.selectTube(tube)) 
						clearSelection();
				
				if (ballAdder.hasFreeSlots(tube)) {
					clearSelection();
					
					ballAdder.addToTube(tube);
					lastPicked = component;
					
					this.selectNode(component);
		
				}
			}
		}
		else if (e.getButton() == MouseEvent.BUTTON3 && lastPicked != null && (e.getWhen() - clickStart < 250)) 
			clearSelection();

			
	}
	
	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseDragged(MouseEvent e) {
		

	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_DELETE) {
//			if (this.deleteSelection(componentGroup))
//				clearSelection();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
		// TODO Auto-generated method stub
		
	}

}
